import re
from time import time
from django.db.models import Q
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from app.forms import BlogForm
from app.models import User
from app.views import isLoginStatus, addMessage, common_data
from learningPlanet.models import JudgeTable, CollectTable, Blog, SearchTable, Category, Tag
from lxml.etree import HTML
from myTool.tools import timestamp_to_date


# 学习星球的主页
# @cache_page(timeout=60, cache='default')  # timeout指定缓存过期时间,cache指定缓存用的数据库，
def index(request, blog_id):
    if request.method == 'GET':
        LoginStatus, userId = isLoginStatus(request)  # 如果是登录状态则显示个人中心

        try:
            isManage = User().get_by_id(id=userId).is_superuser
        except:
            isManage = ''

        # 判断该用户是否收藏了本文
        isCollected = CollectTable().is_collected(userId, blog_id)
        if not isCollected:
            isCollected = ''

        blogObj = Blog.get_by_id(blog_id)
        blogObj.total_views += 1  # 浏览量加一
        blogObj.save()
        authorName = blogObj.author.username  # 作者名称
        authorAvator = blogObj.author.avatar  # 作者头像
        authorId = blogObj.author.id  # 作者的id

        # 如果登录的用户是超级用户(管理员),且该文章的作者也是该管理员则可对文章进行修改操作
        try:
            user = User().get_by_id(id=userId)
            isModify = user.is_superuser and (userId == str(authorId))
            userName = user.username
            userAvatar = user.avatar
        except:
            isModify = ''
            userName = ''
            userAvatar = ''

        blogTitle = blogObj.title  # 文章的标题
        blogContent = blogObj.content  # 文章的内容
        # 判断原文是否被作者删除
        isShow = blogObj.isShow
        if not isShow:
            blogContent = '原文已被作者删除!'
        blogCategory = blogObj.category.title  # 文章的分类
        blogTags = blogObj.tags.split('LLL')  # 文章的标签
        blogTotalViews = blogObj.total_views  # 文章的浏览量
        blogTotalLikes = blogObj.total_likes  # 文章的获赞量
        blogCreatedTime = blogObj.createdTime  # 文章的发布时间
        blogUpdatedTime = blogObj.updatedTime  # 文章的更新时间

        context = locals()
        context.update(common_data())

        return render(request, 'learningplanet.html', context=context)


# 返回评论信息列表
def returnJudgeList(request):
    if request.method == 'POST':

        # 被评论的博客的id
        blogId = request.POST.get('blogId')
        # 找到博客实例对象
        blogObj = Blog().get_by_id(id=blogId)
        resultList = []
        judgeList = JudgeTable.objects.filter(judgeBlog=blogObj)
        if judgeList:
            for judgeObj in judgeList:
                if judgeObj.isShow:  # 如果是可展示的就添加到评论列表中
                    conDic = {
                        'name': judgeObj.judger.username,  # 评论人的名称
                        'avatar': str(judgeObj.judger.avatar),  # 评论人的头像地址
                        'date': str(judgeObj.judgeTime),  # 评论的日期
                        'content': judgeObj.content,  # 评论的内容
                        'id': judgeObj.id,  # 评论的id
                        'judgerId': judgeObj.judger.id  # 评论人的id
                    }
                    resultList.append(conDic)
        return JsonResponse({'judgeList': resultList})


# 删除评论
def deleteJudgeList(request):
    if request.method == 'POST':
        judgeId = request.POST.get('judgeId')
        try:
            judgeObj = JudgeTable.objects.filter(id=judgeId).first()
            judgeObj.isShow = False
            judgeObj.save()

            return JsonResponse({'msg': '删除成功!'})
        except:
            return JsonResponse({'msg': '删除失败!'})


# 增加评论信息
def addJudgeList(request):
    if request.method == 'POST':
        try:
            judgerId = request.POST.get('judgerId')  # 评论人的id
            blogId = request.POST.get('blogId')  # 博客的id
            content = request.POST.get('content')  # 评论的内容
            # date = request.POST.get('date')  # 评论的日期

            judgeObj = JudgeTable(judger_id=judgerId, judgeBlog_id=blogId, content=content)
            judgeObj.save()

            # 同时给被评论的博主通知
            senderId = judgerId
            blogObj = Blog.objects.filter(id=blogId).first()
            blogName = blogObj.title
            receiverId = blogObj.author_id
            content = 'ta评论了你的博客<a href="' + f"{reverse('app:index')}" + f'learningPlanet/{blogId}">{blogName}</a>,快去看看他评论了什么吧!'
            addMessage(senderId, receiverId, content)
            return JsonResponse({'judgeId': judgeObj.id})  # 增加成功就返回该评论的id
        except:
            return JsonResponse({'msg': '评论失败!'})


# 点赞功能
def doCall(request):
    if request.method == 'POST':
        try:
            blogId = request.POST.get('blogId')
            docall = request.POST.get('docall')
            blogObj = Blog.objects.filter(id=blogId).first()
            nowLikes = blogObj.total_likes
            blogObj.total_likes = nowLikes + int(docall)
            blogObj.save()

            if int(docall) > 0:
                senderId = request.POST.get('userId')
                receiverId = blogObj.author_id
                blogName = blogObj.title
                content = 'ta点赞了你的博客<a href="' + f"{reverse('app:index')}" + f'learningPlanet/{blogId}">{blogName}</a>。'
                addMessage(senderId, receiverId, content)

            return JsonResponse({'msg': '点赞成功!'})
        except:
            return JsonResponse({'msg': '点赞失败!'})


# 搜索功能 返回一个博客对象列表
def search(request):
    if request.method == 'POST':
        keyword = request.POST.get('keyword')[:20]  # 关键字
        SearchTable(keyword=keyword).save()  # 保存搜索的关键字

        blogerId = request.POST.get('blogerId')
        if blogerId:  # 用于个人中心的个人博客的搜索
            blogObjs = Blog.objects.filter(author_id=blogerId).filter(  # icontains不区分大小写
                Q(title__icontains=keyword) | Q(category__title__icontains=keyword))
        else:
            blogObjs = Blog.objects.filter(
                Q(title__icontains=keyword.upper()) | Q(category__title__icontains=keyword.upper()))

        blogObjList = []
        if blogObjs:
            N = 1
            for blogObj in blogObjs:
                conDic = {
                    'id': N,
                    'title': blogObj.title,
                    'author': blogObj.author.username,
                    'category': blogObj.category.title,
                    'summary': blogObj.summary,
                    'createdTime': str(blogObj.createdTime).split('.')[0],
                    'blogId': blogObj.id,
                    'updateTime': blogObj.updatedTime,
                    'tags': ' '.join(blogObj.tags.split('LLL')),
                    'views': blogObj.total_views,
                    'likes': blogObj.total_likes,
                    'total_collect': blogObj.total_collect,
                    'total_judge': JudgeTable().get_judge_count_by_blog_id(blogObj.id),

                }
                N += 1
                # 匹配背景图片
                background = re.search(r'<img.*?src="(.*?)".*?>', blogObj.content)
                if background:
                    background = background.group(1)  # 使用匹配到的第一个图片
                else:
                    background = '../static/imgs/bg_preview.png'

                conDic.update({'background': background})

                blogObjList.append(conDic)
                if blogerId and len(conDic['summary']) > 26:
                    conDic['summary'] = conDic['summary'][:23] + '...'
        return JsonResponse({'data': blogObjList})


# 博客编辑
def modifyBlog(request, blog_id, author_id):
    LoginStatus, userId = isLoginStatus(request)  # 如果是登录状态则显示个人中心
    if not LoginStatus or not userId:
        return redirect(reverse("app:index"))

    categoryList = Category.objects.all()

    if request.method == 'GET':
        blog_form = BlogForm
        if blog_id == 'add':
            return render(request, 'modifyBlog.html', context=locals())

        blogObj = Blog.get_by_id(blog_id)

        content = blogObj.content  # 内容
        title = blogObj.title  # 标题
        category = blogObj.category  # 分类
        tags = blogObj.tags.split('LLL')  # 标签

        while len(tags) < 3:
            tags.append('python')

        tag1 = tags[0]
        tag2 = tags[1]
        tag3 = tags[2]

        tagsList = Tag.get_all()
        return render(request, 'modifyBlog.html', context=locals())

    if request.method == 'POST':

        title = request.POST.get('title')
        category = request.POST.get('category')
        tag1 = request.POST.get('tag1')
        tag2 = request.POST.get('tag2')
        tag3 = request.POST.get('tag3')
        content = request.POST.get('content')
        e = HTML(content)
        summary = ''.join(e.xpath('//text()'))[:200]

        categoryObj = Category.get_by_title(category)

        # 附件
        connectedFileList = []
        for i in range(1, 6):
            connectedFileList.append(request.FILES.get(f'connected-file{i}'))

        summary = str(summary) if summary else title  # 匹配中文文字
        tags = 'LLL'.join([tag1, tag2, tag3])  # 以LLL作为分隔符
        updatedTime = timestamp_to_date(time())

        # 如果blogid=add 说明是新增博客
        if blog_id == 'add':
            blog_obj = Blog.update(Blog(), title, author_id, categoryObj.id, tags, content, summary, updatedTime, 1,
                                   connectedFileList)
            blog_id = blog_obj.id

        else:
            blog_obj = Blog.get_by_id(blog_id)
            blog_obj = Blog.update(blog_obj, title, author_id, categoryObj.id, tags, content, summary, updatedTime, 1,
                                   connectedFileList)

        fileNameList = [blog_obj.connectedFile1,  # static/file/2021/08/22/2021年暑假社会实践团队项目报告书.docx
                        blog_obj.connectedFile2,
                        blog_obj.connectedFile3,
                        blog_obj.connectedFile4,
                        blog_obj.connectedFile5]

        # 已有的附件
        havedStr = re.search(r'<p><strong>​附件</strong></p>', content)
        if not havedStr and any(fileNameList):
            content += '<p><strong>​附件</strong></p>'
        for fileName in fileNameList:
            if fileName:
                f_name = str(fileName).split('/')[-1]
                content += f'''<p class="extera_file"><a href="{reverse('app:index')}media/{fileName}" target="_blank">{f_name}</a></p>'''
        blog_obj.content = content
        blog_obj.save()
    # 重定向到展示页面
    return redirect(reverse("learningPlanet:index", kwargs={'blog_id': blog_id}))


# 收藏和取消收藏文章
def collect(request):
    if request.method == 'POST':
        userId = request.POST.get('userId')
        blogId = request.POST.get('blogId')
        isCollected = request.POST.get('isCollected')
        try:
            collectObj = CollectTable.objects.filter(Q(collectorId_id=userId) & Q(blogId_id=blogId)).first()
            if not collectObj:  # 如果是第一次收藏 则需要创建新的对象记录
                collectObj = CollectTable(collectorId_id=userId, blogId_id=blogId)
            collectObj.isCollected = isCollected
            collectObj.save()
        except:
            return JsonResponse({'msg': '收藏操作失败~'})

        # 收藏量加减一
        blog_obj = Blog().get_by_id(id=blogId)
        senderId = userId
        receiverId = blog_obj.author_id
        blogName = blog_obj.title
        blog_obj.total_collect += [-1, 1][int(isCollected)]
        blog_obj.save()
        content = 'ta收藏了你的博客<a href="' + f"{reverse('app:index')}" + f'learningPlanet/{blogId}">{blogName}</a>。'
        addMessage(senderId, receiverId, content)  # 通知该博客的博主
        return JsonResponse({'msg': '收藏成功~'})
